#include <iostream>
using namespace std;
#include <vector>


//version 1   直接找规律
//但是做的时候有一个细节没注意就是，当s的大小小于numRows的时候是可以直接返回的！
//其实走下面逻辑也可以，但是因为 **string oneline(1, s[begin]);**这一句，强行加入了一个字符，如果s.size() < numRows的情况下，begin可能大于n
//这就导致越界访问了


class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1 || s.size() < numRows) return s;

        string ret;
        int max_step = 2 * numRows - 2, n = s.size();
        for(int i = 0; i < numRows; ++i){
            int up = max_step - i * 2, down = max_step - up;
            if(up == 0) swap(up, down);
            //通过up和down迭代取字符即可！
            int begin = i;
            string oneline(1, s[begin]);
            while(begin < n){
                if(begin + up < n)
                    oneline += s[begin + up];
                begin += up;
                if(down != 0 && up != down) std::swap(up, down);
            }
            ret += oneline;
        }
        return ret;
    }
};



//version 2
//所以，只需要在下面判断一下begin是否越界即可 这样就不用判断那么多的特殊条件
class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1) return s;

        string ret;
        int max_step = 2 * numRows - 2, n = s.size();
        for(int i = 0; i < numRows; ++i){
            int up = max_step - i * 2, down = max_step - up;
            if(up == 0) swap(up, down);
            //通过up和down迭代取字符即可！
            int begin = i;
            string oneline;
            if(begin < n) oneline += s[begin];
            while(begin < n){
                if(begin + up < n)
                    oneline += s[begin + up];
                begin += up;
                if(down != 0 && up != down) std::swap(up, down);
            }
            ret += oneline;
        }
        return ret;
    }
};


//按照我的方法写，numRows == 1是必须要特殊判断的！要不然下面变成死循环！

//经过测试，version 1的效率更好！！！ 好了7~8ms